﻿/*!	@file	r_gui_draw.cpp
	@brief	GUI描画クラス
Copyright (c) 2010 Yuya Yamaguchi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "r_gui_draw.h"
#include "r_gui_allocator.h"

#include "../draw/r_draw_vertexbuffer.h"
#include "../draw/r_draw_constantbuffer.h"
#include "../draw/r_draw_texture2d.h"
#include "../draw/r_draw_vertexShader.h"
#include "../draw/r_draw_pixelShader.h"
#include "../draw/r_draw_inputlayout.h"
#include "../draw/r_draw_inputlayout_desc.h"
#include "../draw/r_draw_rasterizerState.h"
#include "../draw/r_draw_blendState.h"
#include "../draw/r_draw_depthStencilState.h"
#include "../draw/r_draw_sampler.h"
#include "../draw/r_draw_context.h"
#include "../draw/r_draw_core.h"
#include "../resource/r_resource_server.h"
#include "../resource/texture/r_resource_texture.h"
#include "../stream/r_stream_default.h"
#include "../util/r_util_str.h"
#include "../math/r_math_matrix44.h"
#include "../window/r_window_systeminfo.h"

namespace r{
	namespace gui{
		namespace draw{
// -------------------------------------------------------

			const r_f32		sRGUIDrawZScale		= 0.001f;
			const r_f32		sRGUIDrawZMax		= 1.0f;
			const r_f32		sRGUIDrawZMin		= -1.0f;
			const r_f32		sRGUIDrawZFar		= sRGUIDrawZMax - 0.001f;

			// データ読み込みパス
			const static	r_cstr	sRGUIDrawFontMapPath		= _RST ( "data\\system\\system_font.fmap" );
			const static	r_cstr	sRGUIDrawFontTexPath		= _RST ( "data\\system\\system_font.dds" );
			const static	r_cstr	sRGUIDrawGUITexPath			= _RST ( "data\\system\\system_gui.dds" );
			const static	r_cstr	sRGUIDrawShaderPath			= _RST ( "data\\win32_dx11\\gui_shader.hlsl" );
			const static	r_cstr	sRGUIDrawShaderEntryVS		= _RST ( "VShader" );
			const static	r_cstr	sRGUIDrawShaderEntryPS		= _RST ( "PShader" );
			const static	r_cstr	sRGUIDrawShaderConstEntryVS	= _RST ( "VCShader" );
			const static	r_cstr	sRGUIDrawShaderConstEntryPS	= _RST ( "PCShader" );


			Draw :: Draw()
				:
				guiVShader ( NULL ),
				guiPShader ( NULL ),
				guiFontTexture ( NULL ),
				guiWidgetTexture ( NULL ),
				guiInputLayout ( NULL ),
				guiBlend ( NULL ),
				guiDepthStateEqual ( NULL ),
				guiDepthStateOverwrite ( NULL ),
				guiDepthStateCash ( NULL )
			{
				r::draw::Core::instance	draw;
				// フォント用のデータ読み込み
				{
					r::stream::ReaderDefault		stream ( sRGUIDrawFontMapPath );
					r::gui::AllocatorData		allocator;
					void*	fontbuff			= allocator()->malloc ( stream.getSize() );
					stream.read ( fontbuff );
					fontData					= reinterpret_cast<FontFile*> ( fontbuff );
					fontData->range				= reinterpret_cast<FontRange*> ( reinterpret_cast<r_size> ( fontData ) + reinterpret_cast<r_size> ( fontData->range ) );
					fontData->info				= reinterpret_cast<FontInfo*> ( reinterpret_cast<r_size> ( fontData ) + reinterpret_cast<r_size> ( fontData->info ) );
					fontData->data				= reinterpret_cast<FontData*> ( reinterpret_cast<r_size> ( fontData ) + reinterpret_cast<r_size> ( fontData->data ) );
				}
				// テクスチャ読み込み
				r::resource::Server::instance	resource;
				guiFontTexturePtr				= resource->loadSync ( sRGUIDrawFontTexPath );
				guiWidgetTexturePtr				= resource->loadSync ( sRGUIDrawGUITexPath );
				guiFontTexture					= r::rtti::dynamicCast<r::resource::ResourceTexture*> ( guiFontTexturePtr->get() );
				guiWidgetTexture				= r::rtti::dynamicCast<r::resource::ResourceTexture*> ( guiWidgetTexturePtr->get() );

				// icon定義
			#define	__DEF_ICONS(iconid, u_from, v_from, u_size, v_size)		{	\
					stRGUIDrawIconInfo&		_tmpicon	=	iconinfo[iconid];		\
					_tmpicon.size[0] = u_size; _tmpicon.size[1] = v_size; _tmpicon.uvmin[0] = pix2uv(u_from); _tmpicon.uvmin[1] = pix2uv(v_from); _tmpicon.uvmax[0] = pix2uv(u_from + u_size); _tmpicon.uvmax[1] = pix2uv(v_from + v_size);}

				__DEF_ICONS ( Icons_Close,		24,		12,		12,		12 );
				__DEF_ICONS ( Icons_Mini,		12,		12,		12,		12 );
				__DEF_ICONS ( Icons_Max,			0,		12,		12,		12 );
				__DEF_ICONS ( Icons_Check,		36,		12,		12,		12 );
				__DEF_ICONS ( Icons_OpenBox,		48,		12,		12,		12 );
				__DEF_ICONS ( Icons_CloseBox,	60,		12,		12,		12 );
				__DEF_ICONS ( Icons_Triangle,	72,		12,		12,		12 );
				__DEF_ICONS ( Icons_Spin,		84,		12,		12,		12 );
				__DEF_ICONS ( Icons_Eye,			96,		12,		12,		12 );
				__DEF_ICONS ( Icons_Link,		108,	12,		12,		12 );
				__DEF_ICONS ( Icons_Play,		0,		24,		12,		12 );
				__DEF_ICONS ( Icons_Pause,		12,		24,		12,		12 );
				__DEF_ICONS ( Icons_Lock,		24,		24,		12,		12 );
				__DEF_ICONS ( Icons_Key,			36,		24,		12,		12 );
				__DEF_ICONS ( Icons_SpotLight,	0,		36,		12,		12 );
				__DEF_ICONS ( Icons_PointLight,	12,		36,		12,		12 );
				__DEF_ICONS ( Icons_DirLight,	24,		36,		12,		12 );
				__DEF_ICONS ( Icons_Camera,		36,		36,		12,		12 );
				__DEF_ICONS ( Icons_Null,		48,		36,		12,		12 );
				__DEF_ICONS ( Icons_Chara,		60,		36,		12,		12 );

				// window定義
			#define	__DEF_WINDOW_PART(src, u, v, w, h, rev)		{	\
					if(rev == 0){src.min.x	= pix2uv(u); src.min.y	= pix2uv(v); src.max.x	= pix2uv(u + w); src.max.y	= pix2uv(v + h);}	\
					else{src.min.x	= pix2uv(u + w); src.min.y	= pix2uv(v + h); src.max.x	= pix2uv(u); src.max.y	= pix2uv(v);}			\
				}
			#define	__DEF_WINDOW(windowid, part_w, part_h, _00_u, _00_v, _01_u, _01_v, _02_u, _02_v, _10_u, _10_v, _11_u, _11_v, _12_u, _12_v, _20_u, _20_v, _21_u, _21_v, _22_u, _22_v, _rot)	{	\
					stRGUIDrawWindowInfo&	_tmpwin	=	windowinfo[windowid];						\
					_tmpwin.size.x	= part_w;	_tmpwin.size.y	= part_h;							\
					__DEF_WINDOW_PART(_tmpwin.rects[0], _00_u, _00_v, part_w, part_h, _rot)			\
					__DEF_WINDOW_PART(_tmpwin.rects[1], _01_u, _01_v, part_w, part_h, _rot)			\
					__DEF_WINDOW_PART(_tmpwin.rects[2], _02_u, _02_v, part_w, part_h, _rot)			\
					__DEF_WINDOW_PART(_tmpwin.rects[3], _10_u, _10_v, part_w, part_h, _rot)			\
					__DEF_WINDOW_PART(_tmpwin.rects[4], _11_u, _11_v, part_w, part_h, _rot)			\
					__DEF_WINDOW_PART(_tmpwin.rects[5], _12_u, _12_v, part_w, part_h, _rot)			\
					__DEF_WINDOW_PART(_tmpwin.rects[6], _20_u, _20_v, part_w, part_h, _rot)			\
					__DEF_WINDOW_PART(_tmpwin.rects[7], _21_u, _21_v, part_w, part_h, _rot)			\
					__DEF_WINDOW_PART(_tmpwin.rects[8], _22_u, _22_v, part_w, part_h, _rot)			\
				}
				__DEF_WINDOW ( WIndows_Window,		4,	4,	12,	0,	16,	0,	20,	0,	12,	4,	16,	4,	20,	4,	12,	8,	16,	8,	20,	8,	0 );
				__DEF_WINDOW ( WIndows_FlatBox,		4,	4,	24,	0,	28,	0,	32,	0,	24,	4,	28,	4,	32,	4,	24,	8,	28,	8,	32,	8,	0 );
				__DEF_WINDOW ( WIndows_FlatArc,		4,	4,	36,	0,	40,	0,	44,	0,	36,	4,	40,	4,	44,	4,	36,	8,	40,	8,	44,	8,	0 );
				__DEF_WINDOW ( WIndows_FlatLArc,		4,	4,	36,	0,	40,	0,	32,	0,	36,	4,	40,	4,	32,	4,	36,	8,	40,	8,	32,	8,	0 );
				__DEF_WINDOW ( WIndows_FlatRArc,		4,	4,	24,	0,	40,	0,	32,	0,	24,	4,	40,	4,	32,	4,	24,	8,	40,	8,	32,	8,	0 );

				__DEF_WINDOW ( WIndows_DownBox,		4,	4,	48,	0,	52,	0,	56,	0,	48,	4,	52,	4,	56,	4,	48,	8,	52,	8,	56,	8,	0 );
				__DEF_WINDOW ( WIndows_DownArc,		4,	4,	60,	0,	64,	0,	68,	0,	60,	4,	64,	4,	68,	4,	60,	8,	64,	8,	68,	8,	0 );
				__DEF_WINDOW ( WIndows_DownLArc,		4,	4,	60,	0,	64,	0,	56,	0,	60,	4,	64,	4,	56,	4,	60,	8,	64,	8,	56,	8,	0 );
				__DEF_WINDOW ( WIndows_DownRArc,		4,	4,	48,	0,	64,	0,	68,	0,	48,	4,	64,	4,	68,	4,	48,	8,	64,	8,	68,	8,	0 );

				__DEF_WINDOW ( WIndows_UpBox,		4,	4,	56,	8,	52,	8,	48,	8,	56,	4,	52,	4,	48,	4,	56,	0,	52,	0,	48,	0,	1 );
				__DEF_WINDOW ( WIndows_UpArc,		4,	4,	68,	8,	64,	8,	60,	8,	68,	4,	64,	4,	60,	4,	68,	0,	64,	0,	60,	0,	1 );
				__DEF_WINDOW ( WIndows_UpLArc,		4,	4,	68,	8,	64,	8,	48,	8,	68,	4,	64,	4,	48,	4,	68,	0,	64,	0,	48,	0,	1 );
				__DEF_WINDOW ( WIndows_UpRArc,		4,	4,	56,	8,	64,	8,	60,	8,	56,	4,	64,	4,	60,	4,	56,	0,	64,	0,	60,	0,	1 );

				// シェーダ読み込み
				{
					const r_cstr	fileName	= sRGUIDrawShaderPath;
					r::stream::ReaderDefault		stream ( fileName );
					void*	tbuff				= gRAllocDefAllocator[eRAllocDef_File]->malloc ( stream.getSize() );
					stream.read ( tbuff );
					guiVShader = r::draw::VertexShader::create( tbuff, stream.getSize(), sRGUIDrawShaderEntryVS, fileName );
					gRAllocDefAllocator[eRAllocDef_File]->free ( tbuff );
				}
				{
					const r_cstr	fileName	= sRGUIDrawShaderPath;
					r::stream::ReaderDefault		stream ( fileName );
					void*	tbuff				= gRAllocDefAllocator[eRAllocDef_File]->malloc ( stream.getSize() );
					stream.read ( tbuff );
					guiPShader = r::draw::PixelShader::create( tbuff, stream.getSize(), sRGUIDrawShaderEntryPS, fileName );
					gRAllocDefAllocator[eRAllocDef_File]->free ( tbuff );
				}
				{
					const r_cstr	fileName	= sRGUIDrawShaderPath;
					r::stream::ReaderDefault		stream ( fileName );
					void*	tbuff				= gRAllocDefAllocator[eRAllocDef_File]->malloc ( stream.getSize() );
					stream.read ( tbuff );
					guiConstVShader = r::draw::VertexShader::create( tbuff, stream.getSize(), sRGUIDrawShaderConstEntryVS, fileName );
					gRAllocDefAllocator[eRAllocDef_File]->free ( tbuff );
				}
				{
					const r_cstr	fileName	= sRGUIDrawShaderPath;
					r::stream::ReaderDefault		stream ( fileName );
					void*	tbuff				= gRAllocDefAllocator[eRAllocDef_File]->malloc ( stream.getSize() );
					stream.read ( tbuff );
					guiConstPShader = r::draw::PixelShader::create( tbuff, stream.getSize(), sRGUIDrawShaderConstEntryPS, fileName );
					gRAllocDefAllocator[eRAllocDef_File]->free ( tbuff );
				}

				r::draw::SamplerDesc	smpdesc;
				smpdesc.filter					= r::draw::SamplerFilterType_MIN_MAG_MIP_LINEAR;
				guiSampler						= r::draw::Sampler::create( smpdesc );

				r::draw::InputLayoutDesc	layoutdesc;
				layoutdesc.add ( r::draw::InputLayoutDescAttr ( _RST ( "POSITION" ), r::draw::InputLayoutFormat_FVec3, 0 ) );
				layoutdesc.add ( r::draw::InputLayoutDescAttr ( _RST ( "TEXTURE" ), r::draw::InputLayoutFormat_FVec2, offsetof ( Vertex, uv ) ) );
				layoutdesc.add ( r::draw::InputLayoutDescAttr ( _RST ( "COLOR" ), r::draw::InputLayoutFormat_UNorm4, offsetof ( Vertex, color ) ) );
				guiInputLayout					= r::draw::InputLayout::create( layoutdesc, guiVShader );

				r::draw::RasterizerDesc	rasterdesc;
				rasterdesc.cullMode				= r::draw::CullMode_None;
				guiRaster						= r::draw::RasterizerState::create( rasterdesc );

				r::draw::BlendStateDesc	blenddesc;
				blenddesc.renderTarget[0].blendEnable	= true;
				blenddesc.renderTarget[0].srcBlend		= r::draw::BlendType_SRC_ALPHA;
				blenddesc.renderTarget[0].destBlend		= r::draw::BlendType_INV_SRC_ALPHA;
				blenddesc.renderTarget[0].blendOp		= r::draw::BlendOp_ADD;
				guiBlend								= r::draw::BlendState::create( blenddesc );

				r::draw::DepthStencilStateDesc	dsNormalDesc;
				r::draw::DepthStencilStateDesc	dsOverDesc;
				dsNormalDesc.depthFunc					= r::draw::DepthComparisonType_EQUAL;
				dsOverDesc.depthFunc					= r::draw::DepthComparisonType_ALWAYS;
				guiDepthStateEqual						= r::draw::DepthStencilState::create( dsNormalDesc );
				guiDepthStateOverwrite					= r::draw::DepthStencilState::create( dsOverDesc );

				cRWindowSystemInfo	winfo;
				guiConstant						= r::draw::ConstantBuffer::create( sizeof ( r::math::Matrix44 ) );
				guiConstant->map();
				r::math::Matrix44	matScreen;
				r_si32	winW;
				r_si32	winH;
				winfo.getWindwowSize ( winW, winH );
				matScreen.orthographics_L ( 0, static_cast<r_f32> ( winH ), static_cast<r_f32> ( winW ), static_cast<r_f32> ( -winH ), sRGUIDrawZMin, sRGUIDrawZMax );
				matScreen.transpose();
				guiConstant->setValue ( &matScreen );
				guiConstant->unMap();
			}

			Draw :: ~Draw()
			{
				r::gui::AllocatorData		allocator;
				allocator()->free ( fontData );
				r::draw::Core::instance		draw;
				guiConstant->destroy();
				guiBlend->destroy();
				guiDepthStateEqual->destroy();
				guiDepthStateOverwrite->destroy();
				guiRaster->destroy();
				guiSampler->destroy();
				guiInputLayout->destroy();
				guiVShader->destroy();
				guiPShader->destroy();
				r::resource::Server::instance	resource;
			}

			void	Draw :: update()
			{
				r::draw::Core::instance		draw;
				removeBuffer.swap();
				// バックバッファを削除します。
				for ( vbuffer_array::iterator it = removeBuffer.getBack().begin(); it != removeBuffer.getBack().end(); ++it ) {
					( *it )->destroy();
				}
				removeBuffer.getBack().clear();
			}

			void	Draw :: begin()
			{
				r::draw::Core::instance		draw;
				r::draw::Context* context		= draw->getContext();
				context->IA_SetInputLayout ( guiInputLayout );
				context->IA_SetPrimitiveTopology ( r::draw::PrimitiveTopologyType_TriangleList );
				context->VS_SetShader ( guiVShader );
				context->PS_SetShader ( guiPShader );
				context->PS_SetSampler ( 0, guiSampler );
				context->VS_SetConstantBuffer ( 0, guiConstant );
				context->RS_SetState ( guiRaster );
				cRWindowSystemInfo	winfo;
				r_si32	winW;
				r_si32	winH;
				winfo.getWindwowSize ( winW, winH );
				context->RS_SetViewPorts ( 1, &r::draw::ViewPortInfo ( 0, 0, static_cast<r_f32> ( winW ), static_cast<r_f32> ( winH ), 0.0f, sRGUIDrawZMax ) );
				r_f32	blendfuct[4]	= {0, 0, 0, 0};
				context->OM_SetBlendState ( guiBlend, blendfuct );
				context->OM_SetDepthStencilState ( guiDepthStateOverwrite, 0 );
				guiDepthStateCash		= guiDepthStateOverwrite;

				setZ ( 0 );
			}

			void	Draw :: drawText ( r_si32 x, r_si32 y, const r_cstr text, const r::math::ColorRGBi color )
			{
				setDepthTestEqual();
				const r_ui32	maxLen	= 256;
				// sjisに変換する
				r_ui32	slen			= r_tm_strlen ( text );
				if ( slen > maxLen ) {
					slen				= maxLen;
				}
				r_mchar	mbstrbuff[maxLen];
				r_ui8*	strbuff	= reinterpret_cast<r_ui8*> ( mbstrbuff );
				Vertex	buffer[maxLen * 6];
				fRStrCopyToMulti ( mbstrbuff, text, maxLen, slen );
				r_f32		tx			= static_cast<r_f32> ( x );
				r_f32		ty			= static_cast<r_f32> ( y );
				r_si32		code		= 0;
				r_si32		cur			= 0;
				r_si32		cnt			= 0;
				for ( r_ui32 i = 0; i < slen; ++i ) {
					if ( ( strbuff[cur] >= 0x81 ) && ( strbuff[cur] < 0xa1 ) ) {
						code		= ( strbuff[cur] << 8 ) | strbuff[cur + 1];
						cur			+= 2;
					} else {
						code		= strbuff[cur];
						++cur;
					}
					// 改行コード
					if ( code == '\n' ) {
						tx			= static_cast<r_f32> ( x );
						ty			+= fontData->fontSpace;
						continue;
					}
					for ( r_ui32 j = 0; j < fontData->numRange; ++j ) {
						if ( ( code >= fontData->range[j].from ) && ( code <= fontData->range[j].to ) ) {
							code -= fontData->range[j].offset;
							FontData*	fdata	= &fontData->data[fontData->info[code].code];
							switch ( fontData->info[code].writeable ) {
							case FontWriteCode_doOutPut: {
								r_si32 idx			= cnt * 6;
								buffer[idx + 0].pos	= r::math::Vector3D ( tx,						ty,							guiZFloat );
								buffer[idx + 1].pos	= r::math::Vector3D ( tx + fontData->fontWidth,	ty,							guiZFloat );
								buffer[idx + 2].pos	= r::math::Vector3D ( tx,						ty + fontData->fontHeight,	guiZFloat );
								buffer[idx + 3].pos	= r::math::Vector3D ( tx,						ty + fontData->fontHeight,	guiZFloat );
								buffer[idx + 4].pos	= r::math::Vector3D ( tx + fontData->fontWidth,	ty,							guiZFloat );
								buffer[idx + 5].pos	= r::math::Vector3D ( tx + fontData->fontWidth,	ty + fontData->fontHeight,	guiZFloat );

								buffer[idx + 0].uv	= fdata->uv1;
								buffer[idx + 1].uv	= r::math::Vector2D ( fdata->uv2.x,	fdata->uv1.y );
								buffer[idx + 2].uv	= r::math::Vector2D ( fdata->uv1.x,	fdata->uv2.y );
								buffer[idx + 3].uv	= r::math::Vector2D ( fdata->uv1.x,	fdata->uv2.y );
								buffer[idx + 4].uv	= r::math::Vector2D ( fdata->uv2.x,	fdata->uv1.y );
								buffer[idx + 5].uv	= fdata->uv2;

								buffer[idx + 0].color	= color;
								buffer[idx + 1].color	= color;
								buffer[idx + 2].color	= color;
								buffer[idx + 3].color	= color;
								buffer[idx + 4].color	= color;
								buffer[idx + 5].color	= color;

								tx += fontData->fontSpace;
								++cnt;
							}
							break;
							case FontWriteCode_doSpace:
								tx += fontData->fontSpace * fontData->info[code].code;
								break;
							case FontWriteCode_doCR:
								tx = static_cast<r_f32> ( x );
								ty += fontData->fontSpace;
								break;
							}
							break;
						}
					}
				}
				if ( cnt == 0 ) {
					return;
				}
				r::draw::Core::instance		draw;
				r::draw::Context* context		= draw->getContext();
				context->PS_SetTexture2D ( 0, guiFontTexture->getResource() );
				r_ui32					numbuff	= cnt * 6;
				r::draw::VertexBuffer*	vbuffer = r::draw::VertexBuffer::create( sizeof ( Vertex ), numbuff );
				vbuffer->map();
				vbuffer->setVertex ( buffer );
				vbuffer->unMap();
				// 描画を実行する
				context->IA_SetVertexBuffer ( 0, vbuffer );
				context->draw ( numbuff );
				// 破棄リストに積む
				removeBuffer.getCurrent().push_back ( vbuffer );
			}

			void	Draw :: drawText ( r_si32 x, r_si32 y, const r_cstr text, const r::math::ColorRGBi color, const r::math::ColorRGBi shadowcolor )
			{
				setDepthTestEqual();
				const r_ui32	maxLen	= 256;
				// sjisに変換する
				r_ui32	slen			= r_tm_strlen ( text );
				if ( slen > maxLen ) {
					slen				= maxLen;
				}
				r::math::Vector3D	textOff		= r::math::Vector3D ( -1.0f, -1.0f, 0.0f );
				r_mchar	strbuff[maxLen];
				Vertex	buffer[maxLen * 6 * 2];
				fRStrCopyToMulti ( strbuff, text, maxLen, slen );
				r_f32		tx			= static_cast<r_f32> ( x );
				r_f32		ty			= static_cast<r_f32> ( y );
				r_si32		code		= 0;
				r_si32		cur			= 0;
				r_si32		cnt			= 0;
				for ( r_ui32 i = 0; i < slen; ++i ) {
					if ( ( strbuff[cur] >= 0x81 ) && ( strbuff[cur] < 0xa1 ) ) {
						code		= ( strbuff[cur] << 8 ) | ( strbuff[cur + 1] );
						cur			+= 2;
					} else {
						code		= strbuff[cur];
						++cur;
					}
					// 改行コード
					if ( code == '\n' ) {
						tx			= static_cast<r_f32> ( x );
						ty			+= fontData->fontSpace;
						continue;
					}
					for ( r_ui32 j = 0; j < fontData->numRange; ++j ) {
						if ( ( code >= fontData->range[j].from ) && ( code <= fontData->range[j].to ) ) {
							code -= fontData->range[j].offset;
							FontData*	fdata	= &fontData->data[fontData->info[code].code];
							switch ( fontData->info[code].writeable ) {
							case FontWriteCode_doOutPut: {
								r_si32 idx			= cnt * 6 * 2;
								buffer[idx + 0].pos	= r::math::Vector3D ( tx,						ty,							guiZFloat );
								buffer[idx + 1].pos	= r::math::Vector3D ( tx + fontData->fontWidth,	ty,							guiZFloat );
								buffer[idx + 2].pos	= r::math::Vector3D ( tx,						ty + fontData->fontHeight,	guiZFloat );
								buffer[idx + 3].pos	= r::math::Vector3D ( tx,						ty + fontData->fontHeight,	guiZFloat );
								buffer[idx + 4].pos	= r::math::Vector3D ( tx + fontData->fontWidth,	ty,							guiZFloat );
								buffer[idx + 5].pos	= r::math::Vector3D ( tx + fontData->fontWidth,	ty + fontData->fontHeight,	guiZFloat );

								buffer[idx + 0].uv	= fdata->uv1;
								buffer[idx + 1].uv	= r::math::Vector2D ( fdata->uv2.x,	fdata->uv1.y );
								buffer[idx + 2].uv	= r::math::Vector2D ( fdata->uv1.x,	fdata->uv2.y );
								buffer[idx + 3].uv	= r::math::Vector2D ( fdata->uv1.x,	fdata->uv2.y );
								buffer[idx + 4].uv	= r::math::Vector2D ( fdata->uv2.x,	fdata->uv1.y );
								buffer[idx + 5].uv	= fdata->uv2;

								buffer[idx + 6].pos	= buffer[idx + 0].pos + textOff;
								buffer[idx + 7].pos	= buffer[idx + 1].pos + textOff;
								buffer[idx + 8].pos	= buffer[idx + 2].pos + textOff;
								buffer[idx + 9].pos	= buffer[idx + 3].pos + textOff;
								buffer[idx + 10].pos	= buffer[idx + 4].pos + textOff;
								buffer[idx + 11].pos	= buffer[idx + 5].pos + textOff;

								buffer[idx + 6].uv	= buffer[idx + 0].uv;
								buffer[idx + 7].uv	= buffer[idx + 1].uv;
								buffer[idx + 8].uv	= buffer[idx + 2].uv;
								buffer[idx + 9].uv	= buffer[idx + 3].uv;
								buffer[idx + 10].uv	= buffer[idx + 4].uv;
								buffer[idx + 11].uv	= buffer[idx + 5].uv;

								buffer[idx + 0].color	= shadowcolor;
								buffer[idx + 1].color	= shadowcolor;
								buffer[idx + 2].color	= shadowcolor;
								buffer[idx + 3].color	= shadowcolor;
								buffer[idx + 4].color	= shadowcolor;
								buffer[idx + 5].color	= shadowcolor;

								buffer[idx + 6].color	= color;
								buffer[idx + 7].color	= color;
								buffer[idx + 8].color	= color;
								buffer[idx + 9].color	= color;
								buffer[idx + 10].color	= color;
								buffer[idx + 11].color	= color;

								tx += fontData->fontSpace;
								++cnt;
							}
							break;
							case FontWriteCode_doSpace:
								tx += fontData->fontSpace * fontData->info[code].code;
								break;
							case FontWriteCode_doCR:
								tx = static_cast<r_f32> ( x );
								ty += fontData->fontSpace;
								break;
							}
							break;
						}
					}
				}
				r::draw::Core::instance		draw;
				r::draw::Context* context		= draw->getContext();
				context->PS_SetTexture2D ( 0, guiFontTexture->getResource() );
				r_ui32	numbuff				= cnt * 6 * 2;
				r::draw::VertexBuffer*			vbuffer = r::draw::VertexBuffer::create( sizeof ( Vertex ), numbuff );
				vbuffer->map();
				vbuffer->setVertex ( buffer );
				vbuffer->unMap();
				// 描画を実行する
				context->IA_SetVertexBuffer ( 0, vbuffer );
				context->draw ( numbuff );
				// 破棄リストに積む
				removeBuffer.getCurrent().push_back ( vbuffer );
			}

			void	Draw :: calcTextPixPos ( const r_cstr text, r_ui32 pos, r::math::Vector2D& off )
			{
				const r_ui32	maxLen	= 256;
				// sjisに変換する
				r_ui32	slen			= r_tm_strlen ( text );
				if ( slen > maxLen ) {
					slen				= maxLen;
				}
				r_mchar	strbuff[maxLen];
				fRStrCopyToMulti ( strbuff, text, maxLen, slen );
				r_f32		tx			= 0;
				r_f32		ty			= 0;
				r_si32		code		= 0;
				r_si32		cur			= 0;
				r_si32		cnt			= 0;
				for ( r_ui32 i = 0; i < slen; ++i ) {
					if ( i == pos ) {
						break;
					}
					if ( ( strbuff[cur] >= 0x81 ) && ( strbuff[cur] < 0xa1 ) ) {
						code		= ( strbuff[cur] << 8 ) | ( strbuff[cur + 1] );
						cur			+= 2;
					} else {
						code		= strbuff[cur];
						++cur;
					}
					// 改行コード
					if ( code == '\n' ) {
						tx			= 0;
						ty			+= fontData->fontSpace;
						continue;
					}
					for ( r_ui32 j = 0; j < fontData->numRange; ++j ) {
						if ( ( code >= fontData->range[j].from ) && ( code <= fontData->range[j].to ) ) {
							code -= fontData->range[j].offset;
							FontData*	fdata	= &fontData->data[fontData->info[code].code];
							switch ( fontData->info[code].writeable ) {
							case FontWriteCode_doOutPut: {
								tx += fontData->fontSpace;
								++cnt;
							}
							break;
							case FontWriteCode_doSpace:
								tx += fontData->fontSpace * fontData->info[code].code;
								break;
							case FontWriteCode_doCR:
								tx = 0;
								ty += fontData->fontSpace;
								break;
							}
							break;
						}
					}
				}
				off.x				= tx;
				off.y				= ty;
			}

			void	Draw :: calcTextPixSize ( const r_cstr text, r::math::Vector2D& max )
			{
				const r_ui32	maxLen	= 256;
				// sjisに変換する
				r_ui32	slen			= r_tm_strlen ( text );
				if ( slen > maxLen ) {
					slen				= maxLen;
				}
				r_mchar	strbuff[maxLen];
				fRStrCopyToMulti ( strbuff, text, maxLen, slen );
				r_f32		tx			= 0;
				r_f32		ty			= 0;
				r_si32		code		= 0;
				r_si32		cur			= 0;
				r_si32		cnt			= 0;
				max.x					= 0;
				max.y					= 0;
				for ( r_ui32 i = 0; i < slen; ++i ) {
					if ( ( strbuff[cur] >= 0x81 ) && ( strbuff[cur] < 0xa1 ) ) {
						code		= ( strbuff[cur] << 8 ) | ( strbuff[cur + 1] );
						cur			+= 2;
					} else {
						code		= strbuff[cur];
						++cur;
					}
					// 改行コード
					if ( code == '\n' ) {
						tx			= 0;
						ty			+= fontData->fontSpace;
						continue;
					}
					for ( r_ui32 j = 0; j < fontData->numRange; ++j ) {
						if ( ( code >= fontData->range[j].from ) && ( code <= fontData->range[j].to ) ) {
							code -= fontData->range[j].offset;
							FontData*	fdata	= &fontData->data[fontData->info[code].code];
							switch ( fontData->info[code].writeable ) {
							case FontWriteCode_doOutPut: {
								if ( max.x < ( tx + fontData->fontWidth ) ) {
									max.x = tx + fontData->fontWidth;
								}
								tx += fontData->fontSpace;
								if ( max.x < tx ) {
									max.x = tx;
								}
								if ( max.y < ( ty + fontData->fontHeight ) ) {
									max.y	= ty + fontData->fontHeight;
								}
								++cnt;
							}
							break;
							case FontWriteCode_doSpace:
								tx += fontData->fontSpace * fontData->info[code].code;
								if ( max.x < tx ) {
									max.x = tx;
								}
								break;
							case FontWriteCode_doCR:
								tx = 0;
								ty += fontData->fontSpace;
								if ( max.y < ty ) {
									max.x	= ty;
								}
								break;
							}
							break;
						}
					}
				}
			}

			void	Draw :: asignGUITexture()
			{
				r::draw::Core::instance		draw;
				r::draw::Context* context	= draw->getContext();
				context->PS_SetTexture2D ( 0, guiWidgetTexture->getResource() );
			}

			void	Draw :: asignTextureResource( r::resource::ResourcePtr tex )
			{
				if( !r::resource::isEnable( tex ) ){
					return;
				}
				r::resource::ResourceTexture* texres = r::rtti::dynamicCast<r::resource::ResourceTexture*>( tex->get() );
				r::draw::Core::instance		draw;
				r::draw::Context* context	= draw->getContext();
				context->PS_SetTexture2D ( 0, texres->getResource() );
			}

			void	Draw :: asignGUIDefaultShader()
			{
				r::draw::Core::instance		draw;
				r::draw::Context* context	= draw->getContext();
				context->VS_SetShader ( guiVShader );
				context->PS_SetShader ( guiPShader );
			}

			void	Draw :: asignGUIConstantShader()
			{
				r::draw::Core::instance		draw;
				r::draw::Context* context	= draw->getContext();
				context->VS_SetShader ( guiConstVShader );
				context->PS_SetShader ( guiConstPShader );
			}

			void	Draw :: drawIcon ( r_si32 x, r_si32 y, r_si32 icons, const r::math::ColorRGBi color, r_si32 rotate )
			{
				setDepthTestEqual();
				r::draw::Core::instance		draw;
				r::draw::Context* context	= draw->getContext();

				const r_ui32	numbuff		= 3 * 2;
				Vertex	buffer[numbuff];
				for ( r_ui32 i = 0; i < numbuff; ++i ) {
					buffer[i].color			= color;
					buffer[i].pos.z			= guiZFloat;
				}
				stRGUIDrawIconInfo&		_tmpicon	=	iconinfo[icons];
				buffer[0].pos.x				=	static_cast<r_f32> ( x );
				buffer[0].pos.y				=	static_cast<r_f32> ( y );
				buffer[1].pos.x				=	buffer[0].pos.x + _tmpicon.size[0];
				buffer[1].pos.y				=	buffer[0].pos.y;
				buffer[2].pos.x				=	buffer[0].pos.x;
				buffer[2].pos.y				=	buffer[0].pos.y + _tmpicon.size[1];

				buffer[3].pos.x				=	buffer[2].pos.x;
				buffer[3].pos.y				=	buffer[2].pos.y;
				buffer[4].pos.x				=	buffer[1].pos.x;
				buffer[4].pos.y				=	buffer[1].pos.y;
				buffer[5].pos.x				=	buffer[1].pos.x;
				buffer[5].pos.y				=	buffer[2].pos.y;

				switch ( rotate ) {
				case IconsRotate_0:
					buffer[0].uv.x				=	_tmpicon.uvmin[0];
					buffer[0].uv.y				=	_tmpicon.uvmin[1];
					buffer[1].uv.x				=	_tmpicon.uvmax[0];
					buffer[1].uv.y				=	_tmpicon.uvmin[1];
					buffer[2].uv.x				=	_tmpicon.uvmin[0];
					buffer[2].uv.y				=	_tmpicon.uvmax[1];

					buffer[3].uv.x				=	buffer[2].uv.x;
					buffer[3].uv.y				=	buffer[2].uv.y;
					buffer[4].uv.x				=	buffer[1].uv.x;
					buffer[4].uv.y				=	buffer[1].uv.y;
					buffer[5].uv.x				=	buffer[1].uv.x;
					buffer[5].uv.y				=	buffer[2].uv.y;
					break;
				case IconsRotate_90:
					buffer[0].uv.x				=	_tmpicon.uvmin[0];
					buffer[0].uv.y				=	_tmpicon.uvmax[1];
					buffer[1].uv.x				=	_tmpicon.uvmin[0];
					buffer[1].uv.y				=	_tmpicon.uvmin[1];
					buffer[2].uv.x				=	_tmpicon.uvmax[0];
					buffer[2].uv.y				=	_tmpicon.uvmax[1];

					buffer[3].uv.x				=	_tmpicon.uvmax[0];
					buffer[3].uv.y				=	_tmpicon.uvmax[1];
					buffer[4].uv.x				=	_tmpicon.uvmin[0];
					buffer[4].uv.y				=	_tmpicon.uvmin[1];
					buffer[5].uv.x				=	_tmpicon.uvmax[0];
					buffer[5].uv.y				=	_tmpicon.uvmin[1];
					break;
				case IconsRotate_270:
					buffer[0].uv.x				=	_tmpicon.uvmax[0];
					buffer[0].uv.y				=	_tmpicon.uvmin[1];
					buffer[1].uv.x				=	_tmpicon.uvmax[0];
					buffer[1].uv.y				=	_tmpicon.uvmax[1];
					buffer[2].uv.x				=	_tmpicon.uvmin[0];
					buffer[2].uv.y				=	_tmpicon.uvmin[1];

					buffer[3].uv.x				=	_tmpicon.uvmin[0];
					buffer[3].uv.y				=	_tmpicon.uvmin[1];
					buffer[4].uv.x				=	_tmpicon.uvmax[0];
					buffer[4].uv.y				=	_tmpicon.uvmax[1];
					buffer[5].uv.x				=	_tmpicon.uvmin[0];
					buffer[5].uv.y				=	_tmpicon.uvmax[1];
					break;
				case IconsRotate_180:
					buffer[0].uv.x				=	_tmpicon.uvmax[0];
					buffer[0].uv.y				=	_tmpicon.uvmax[1];
					buffer[1].uv.x				=	_tmpicon.uvmin[0];
					buffer[1].uv.y				=	_tmpicon.uvmax[1];
					buffer[2].uv.x				=	_tmpicon.uvmax[0];
					buffer[2].uv.y				=	_tmpicon.uvmin[1];

					buffer[3].uv.x				=	_tmpicon.uvmax[0];
					buffer[3].uv.y				=	_tmpicon.uvmin[1];
					buffer[4].uv.x				=	_tmpicon.uvmin[0];
					buffer[4].uv.y				=	_tmpicon.uvmax[1];
					buffer[5].uv.x				=	_tmpicon.uvmin[0];
					buffer[5].uv.y				=	_tmpicon.uvmin[1];
					break;
				}

				r::draw::VertexBuffer*			vbuffer = r::draw::VertexBuffer::create( sizeof ( Vertex ), numbuff );
				vbuffer->map();
				vbuffer->setVertex ( buffer );
				vbuffer->unMap();
				// 描画を実行する
				context->IA_SetVertexBuffer ( 0, vbuffer );
				context->draw ( numbuff );
				// 破棄リストに積む
				removeBuffer.getCurrent().push_back ( vbuffer );
			}

			void	Draw :: drawWindow ( r_si32 x, r_si32 y, r_si32 w, r_si32 h, r_si32 windows, const r::math::ColorRGBi color )
			{
				setDepthTestEqual();
				const r_ui32	numbuff		= 9 * 3 * 2;
				Vertex	buffer[numbuff];
				for ( r_ui32 i = 0; i < numbuff; ++i ) {
					buffer[i].color			= color;
					buffer[i].pos.z			= guiZFloat;
				}
				const	stRGUIDrawWindowInfo&	_tmpwin	=	windowinfo[windows];
				const	r_f32			vx[4]		= {
					static_cast<r_f32> ( x ),
					static_cast<r_f32> ( x )			+	_tmpwin.size.x,
					static_cast<r_f32> ( x	+	w )	-	_tmpwin.size.x,
					static_cast<r_f32> ( x	+	w )
				};
				const	r_f32			vy[4]		= {
					static_cast<r_f32> ( y ),
					static_cast<r_f32> ( y )			+	_tmpwin.size.y,
					static_cast<r_f32> ( y	+	h )	-	_tmpwin.size.y,
					static_cast<r_f32> ( y	+	h )
				};
				const	r_ui32	uindex[3 * 2 * 3]	= {
					0, 1, 0, 0, 1, 1, 1, 2, 1, 1, 2, 2, 2, 3, 2, 2, 3, 3
				};
				const	r_ui32	vindex[3 * 2]	= {
					0, 0, 1, 1, 0, 1
				};
				const	r_bool	uminmax[3 * 2]	= {
					false, true, false, false, true, true
				};
				const	r_bool	vminmax[3 * 2]	= {
					false, false, true, true, false, true
				};

				r_ui32	c					= 0;
				for ( r_ui32 j = 0; j < 3; ++j ) {
					for ( r_ui32 i = 0; i < 3 * 2 * 3; ++i ) {
						r_ui32	xi			= uindex[i];
						r_ui32	yi			= j + vindex[i % ( 3 * 2 ) ];
						r_ui32	ui			= i % ( 3 * 2 );
						r_ui32	uvi			= c / ( 3 * 2 );
						buffer[c].pos.x		=	vx[xi];
						buffer[c].pos.y		=	vy[yi];
						buffer[c].uv.x		=	( uminmax[ui] ) ? _tmpwin.rects[uvi].max.x : _tmpwin.rects[uvi].min.x;
						buffer[c].uv.y		=	( vminmax[ui] ) ? _tmpwin.rects[uvi].max.y : _tmpwin.rects[uvi].min.y;
						++c;
					}
				}

				r::draw::Core::instance	draw;
				r::draw::Context*		context	= draw->getContext();
				r::draw::VertexBuffer*	vbuffer = r::draw::VertexBuffer::create( sizeof ( Vertex ), numbuff );
				vbuffer->map();
				vbuffer->setVertex ( buffer );
				vbuffer->unMap();
				// 描画を実行する
				context->IA_SetVertexBuffer ( 0, vbuffer );
				context->draw ( numbuff );
				// 破棄リストに積む
				removeBuffer.getCurrent().push_back ( vbuffer );
			}

			void	Draw :: drarwRect ( const Rect& rect, const r::math::ColorRGBi color )
			{
				setDepthTestEqual();
				r::draw::Core::instance		draw;
				r::draw::Context* context		= draw->getContext();

				const r_ui32	numbuff		= 3 * 2;
				Vertex	buffer[numbuff];
				for ( r_ui32 i = 0; i < numbuff; ++i ) {
					buffer[i].color			= color;
					buffer[i].pos.z			= guiZFloat;
				}
				buffer[0].pos.x				=	static_cast<r_f32> ( rect.x );
				buffer[0].pos.y				=	static_cast<r_f32> ( rect.y );
				buffer[1].pos.x				=	buffer[0].pos.x + rect.width;
				buffer[1].pos.y				=	buffer[0].pos.y;
				buffer[2].pos.x				=	buffer[0].pos.x;
				buffer[2].pos.y				=	buffer[0].pos.y + rect.height;

				buffer[3].pos.x				=	buffer[2].pos.x;
				buffer[3].pos.y				=	buffer[2].pos.y;
				buffer[4].pos.x				=	buffer[1].pos.x;
				buffer[4].pos.y				=	buffer[1].pos.y;
				buffer[5].pos.x				=	buffer[1].pos.x;
				buffer[5].pos.y				=	buffer[2].pos.y;

				buffer[0].uv.x				=	static_cast<r_f32> ( rect.uvX );
				buffer[0].uv.y				=	static_cast<r_f32> ( rect.uvY );
				buffer[1].uv.x				=	buffer[0].uv.x + rect.uvWidth;
				buffer[1].uv.y				=	buffer[0].uv.y;
				buffer[2].uv.x				=	buffer[0].uv.x;
				buffer[2].uv.y				=	buffer[0].uv.y + rect.uvHeight;

				buffer[3].uv.x				=	buffer[2].uv.x;
				buffer[3].uv.y				=	buffer[2].uv.y;
				buffer[4].uv.x				=	buffer[1].uv.x;
				buffer[4].uv.y				=	buffer[1].uv.y;
				buffer[5].uv.x				=	buffer[1].uv.x;
				buffer[5].uv.y				=	buffer[2].uv.y;

				r::draw::VertexBuffer*			vbuffer = r::draw::VertexBuffer::create( sizeof ( Vertex ), numbuff );
				vbuffer->map();
				vbuffer->setVertex ( buffer );
				vbuffer->unMap();
				// 描画を実行する
				context->IA_SetVertexBuffer ( 0, vbuffer );
				context->draw ( numbuff );
				// 破棄リストに積む
				removeBuffer.getCurrent().push_back ( vbuffer );
			}

			void	Draw :: drawVertexTriList ( const Vertex* varray, r_ui32 vertexNum )
			{
				setDepthTestEqual();
				r::draw::Core::instance		draw;
				r::draw::Context* context		= draw->getContext();
				r::draw::VertexBuffer*			vbuffer = r::draw::VertexBuffer::create( sizeof ( Vertex ), vertexNum );
				vbuffer->map();
				vbuffer->setVertex ( varray );
				vbuffer->unMap();
				// 描画を実行する
				context->IA_SetVertexBuffer ( 0, vbuffer );
				context->draw ( vertexNum );
				// 破棄リストに積む
				removeBuffer.getCurrent().push_back ( vbuffer );
			}

			void	Draw :: setRect ( r_si32 x, r_si32 y, r_si32 w, r_si32 h )
			{
				guiRectX					= x;
				guiRectY					= y;
				guiRectW					= w;
				guiRectH					= h;
			}

			void	Draw :: getRect ( r_si32& x, r_si32& y, r_si32& w, r_si32& h ) const
			{
				x							= guiRectX;
				y							= guiRectY;
				w							= guiRectW;
				h							= guiRectH;
			}

			void	Draw :: asignRect()
			{
				setDepthTestAlways();
				r::draw::Core::instance		draw;
				r::draw::Context* context	= draw->getContext();


				const r_ui32	numbuff		= 3 * 2;
				Vertex	buffer[numbuff];
				for ( r_ui32 i = 0; i < numbuff; ++i ) {
					buffer[i].color			= r::math::ColorRGBi ( 0, 0, 0, 0 );
					buffer[i].pos.z			= guiZFloat;
					buffer[i].uv			= r::math::Vector2D ( 0, 0 );
				}
				buffer[0].pos.x				=	static_cast<r_f32> ( guiRectX );
				buffer[0].pos.y				=	static_cast<r_f32> ( guiRectY );
				buffer[1].pos.x				=	buffer[0].pos.x + guiRectW;
				buffer[1].pos.y				=	buffer[0].pos.y;
				buffer[2].pos.x				=	buffer[0].pos.x;
				buffer[2].pos.y				=	buffer[0].pos.y + guiRectH;

				buffer[3].pos.x				=	buffer[2].pos.x;
				buffer[3].pos.y				=	buffer[2].pos.y;
				buffer[4].pos.x				=	buffer[1].pos.x;
				buffer[4].pos.y				=	buffer[1].pos.y;
				buffer[5].pos.x				=	buffer[1].pos.x;
				buffer[5].pos.y				=	buffer[2].pos.y;


				r::draw::VertexBuffer*			vbuffer = r::draw::VertexBuffer::create( sizeof ( Vertex ), numbuff );
				vbuffer->map();
				vbuffer->setVertex ( buffer );
				vbuffer->unMap();
				// 描画を実行する
				context->IA_SetVertexBuffer ( 0, vbuffer );
				context->draw ( numbuff );
				// 破棄リストに積む
				removeBuffer.getCurrent().push_back ( vbuffer );
			}


			r_bool	Draw :: calcRect ( r_si32 px, r_si32 py, r_si32 pw, r_si32 ph, r_si32 cx, r_si32 cy, r_si32 cw, r_si32 ch, r_si32& x, r_si32& y, r_si32& w, r_si32& h ) const
			{
				x							= px < cx ? cx : px;
				y							= py < cy ? cy : py;
				r_si32	tpw					= px + pw;
				r_si32	tcw					= cx + cw;
				w							= ( tpw > tcw ? tcw : tpw ) - x;
				r_si32	tph					= py + ph;
				r_si32	tch					= cy + ch;
				h							= ( tph > tch ? tch : tph ) - y;
				if ( ( cx > tpw ) || ( ( cx + cw ) < 0 ) || ( cy > tph ) || ( ( cy + ch ) < 0 ) ) {
					return false;
				}
				return true;
			}

			void	Draw :: setDepthTestAlways()
			{
				if ( guiDepthStateCash != guiDepthStateOverwrite ) {
					guiDepthStateCash			= guiDepthStateOverwrite;
					r::draw::Core::instance		draw;
					draw->getContext()->OM_SetDepthStencilState ( guiDepthStateCash, 0 );
				}
			}

			void	Draw :: setDepthTestEqual()
			{
				if ( guiDepthStateCash != guiDepthStateEqual ) {
					guiDepthStateCash = guiDepthStateEqual;
					r::draw::Core::instance		draw;
					draw->getContext()->OM_SetDepthStencilState ( guiDepthStateCash, 0 );
				}
			}

			void	Draw :: setZ ( r_si32 z )
			{
				guiZInt				= z;
				guiZFloat			= sRGUIDrawZFar - ( z * sRGUIDrawZScale );
			}

			r_si32	Draw :: getZ() const
			{
				return guiZInt;
			}

			r_f32	Draw :: getFloatZ() const
			{
				return guiZFloat;
			}

			r_f32	Draw :: pix2uv ( r_si32 val ) const
			{
				return val	* ( 1.0f / 128.0f );
			}
		}
	}
}